var enabled;
var color;
var extUrl = chrome.extension.getURL("");

var boxManager = (function () {
	var boxOpen = false;
	var defaultText = "Write your comment here";
	
	function buildTitleDiv(title, onClose) {
	
		var titleDiv = document.createElement('div');
		titleDiv.className = "comment_title";
		
		titleSpan = document.createElement('span');
		titleSpan.innerHTML = title;
		titleSpan.className = "comment_title_text";
		
		closeImg = buildImage(extUrl + "images/close_button.png",15,15);
		closeImg.className += " comment_title_close";
		closeImg.onclick = onClose;
		
		titleDiv.appendChild(titleSpan);
		titleDiv.appendChild(closeImg);
		
		return titleDiv;
	}
	
	function buildImage(src, height, width){
		var img = document.createElement('img');
		img.src = src;
		img.className = "comment_image";
		img.style.height = height +"px";
		img.style.width = width + "px";
		return img;
	}
	
	function buildBottom(onComment, onCancel) {
		var bottomDiv = document.createElement('div');
		bottomDiv.className = "comment_buttom";
		
		var commentImage = buildImage(extUrl + "images/comment_button.png",24,69);
		commentImage.onclick = onComment;
		commentImage.className += " comment_buttom_comment";
		
		var cancelImage = buildImage(extUrl + "images/cancel_button.png",24,69);
		cancelImage.onclick = onCancel;
		cancelImage.className += " comment_buttom_cancel";
		
		bottomDiv.appendChild(cancelImage);
		bottomDiv.appendChild(commentImage);
		
		return bottomDiv;
	}
	
	function buildCommentBox(position) {

		var leftOffset = (position.left + 300) - window.innerWidth ;
		if (leftOffset > 0){
			position.left -= leftOffset;
		}
		var topOffset = (position.top + 200) - (window.innerHeight + window.scrollY) ;
		if (topOffset > 0){
			position.top -= topOffset;
		}
		
		var commentDiv = document.createElement('div');
		commentDiv.className = "comment_box";
		commentDiv.draggable = "true";
		commentDiv.style.top = position.top + "px";
		commentDiv.style.left = position.left + "px";
		return commentDiv;
		
	}
	function buildTextArea(text, reviewMode, postedBy) {
		var textDiv = document.createElement('div');
		textDiv.className = "comment_text_wrapper";
		
		var textArea = document.createElement('textarea');
		textArea.className = "comment_text_area";
		textArea.style.height = reviewMode ? "42px" : "123px";
		textArea.placeholder = defaultText;
				
		if (reviewMode){
			var reviewTextDiv = document.createElement('div');
			reviewTextDiv.className = "comment_text_review_wrapper";
			var textSpan = document.createElement('span');
			textSpan.innerText = text;
			reviewTextDiv.appendChild(textSpan);
			if (postedBy){
				reviewTextDiv.appendChild(buildPostedBy(postedBy));
			}
			textDiv.appendChild(reviewTextDiv);
			
		}
		if (text && !reviewMode) {
			textArea.innerText = text;
		} 
		textDiv.appendChild(textArea);
		return textDiv;
	}
	
	function buildPostedBy(postedBy){
		var postedBySpan = document.createElement('span');
		postedBySpan.className = "comment_posted_by";
		postedBySpan.innerText = "Posted by " + postedBy;
		return postedBySpan;
	}	
	
	
	function openCommentBox(position, title, onComment, text, postedBy, reviewMode) {
		function removeBox(box){
			document.body.removeChild(box);
			boxOpen = false;
			document.body.removeEventListener("click",externalClick);
		}
		
		function externalClick(e){
			removeBox(box);
			onComment(false);
		}
		var startOffset;
		function handleDragStart(e){
			//e.preventDefault();
			var dragIcon = document.createElement('img');
			dragIcon.src = '';
			dragIcon.width = 0;
			e.dataTransfer.setDragImage(dragIcon, 0, 0);
			startOffset = {
				top: parseInt(box.style.top) - (e.clientY + window.scrollY),
				left: parseInt(box.style.left) - e.clientX
			}
		}
		function handleDrag(e){
			e.preventDefault();
			box.style.top = e.clientY + window.scrollY + startOffset.top +"px";
			box.style.left = e.clientX + startOffset.left + "px";
			
		}
		function handleDragOver(e) {
		  if (e.preventDefault) {
			e.preventDefault(); // Necessary. Allows us to drop.
		  }
		  e.dataTransfer.dropEffect = 'move';  // See the section on the DataTransfer object.
		  return false;
		}
		if (!boxOpen){
			var box = buildCommentBox(position);
			title = title.substr(0, 25);
			var title = buildTitleDiv(title, function () {
					removeBox(box)
					onComment(false);
				});
			var textDiv = buildTextArea(text, reviewMode, postedBy);
			var textArea = textDiv.getElementsByTagName('textarea')[0];
			var comment = buildBottom(function () {
					removeBox(box);
					onComment(textArea.value);
				}, function(){
					removeBox(box);
					onComment(false);
				});
			box.appendChild(title);
			box.appendChild(comment);		
			box.appendChild(textDiv);
			box.onkeydown = function(e){
				if (e.keyCode == 13){ //Enter
					//removeBox(box);
					//onComment(textArea.value);
				}else if(e.keyCode == 27){ //Esc
					removeBox(box)
					onComment(false);
				}
			}
			box.onclick = function (e){
				e.stopPropagation();
			}
			//box.addEventListener('dragend', handleDragEnd,false); 
			box.addEventListener('dragstart', handleDragStart, false);
			box.addEventListener('drag', handleDrag, false);
			box.addEventListener('dragover', handleDragOver, false);
			boxOpen = true;
			document.body.addEventListener("click", externalClick);
			document.body.appendChild(box);
			textArea.focus();
		}
	}
	return {
		openCommentBox : openCommentBox
	}
})();
//Background call these functions
function disable(comments){
	enabled = false;
	Comments.disable(comments);
}

function enable(comments){
	enabled = true;
	Comments.enable(comments);
}

var Comments = (function(){
	var pageComments;
	function disable(comments){
		DOM.colorComments(comments, true);
	}

	function enable(comments){
		DOM.colorComments(comments);
	}
	
	function showComments(comments) {
		pageComments = comments;
		DOM.colorComments(comments);
	}

	return {
		disable: disable,
		enable: enable,
		showComments: showComments
	}
})();

var DOM = (function(){
	function findElement(data) {
		var elemWithId = document.getElementById(data.firstId.id);
		if (data.firstId.isParent) {
			return elemWithId;
		} else {
			var sameTypeElements = elemWithId.getElementsByTagName(data.parentType);
			for (var j = 0; j < sameTypeElements.length; j++) {
				if (sameTypeElements[j].innerHTML.indexOf(data.text) != -1) {
					return sameTypeElements[j];
				}
			}
		}
		return null;
	}
	function commentClick(e){
		e.stopPropagation();
		var text = this.innerHTML;
		var title = this.title.split(", Posted by ");
		var val = title[0];
		var posted = title[1];
		var commentId = this.id;
		boxManager.openCommentBox({
			top : e.clientY + window.scrollY,
			left : e.clientX
		}, text, function (commentValue) {
			Background.updateComment({commentId: commentId, userId:"1"});
		}, val, posted, true);
	}
	function getColorSapn(colorText, commentValue, postedBy, id){
		var colorSpan = document.createElement('span');
		colorSpan.id = id;
		colorSpan.innerHTML = colorText;
		colorSpan.style.backgroundColor = color;
		colorSpan.style.cursor = "pointer";
		colorSpan.className = "comment_color";
		colorSpan.style.borderRadius = "6px";
		if (postedBy){
			colorSpan.title = commentValue + ", Posted by " + postedBy;
		}else{
			colorSpan.style.border = "1px rgba(102, 145, 106, 0.8) solid";
		}
		return colorSpan;
	}
	
	function bindComments(parent){
		var commentSpans = parent.getElementsByTagName("span");
		for (var i=0; i< commentSpans.length; i++){
			commentSpans[i].onclick = commentClick;
		}
	}

	function colorCommentText(parent, colorText, commentValue, postedBy, id) {
		parent.innerHTML = parent.innerHTML.replace(colorText, getColorSapn(colorText, commentValue, postedBy, id).outerHTML);
		bindComments(parent);
	}

	function getFirstElementWithId(element) {
		if (element.id) {
			return {
				id : element.id,
				isParent : true
			};
		}
		while (element && (element != element.parentElement) && !element.id) {
			element = element.parentElement;
		}
		return {
			id : element.id,
			isParent : false
		};
	}
	
	function handleSelection(e) {
		if (enabled){
			var selected = window.getSelection();
			var anchorOffset = selected.extentOffset;
			var extentOffset = selected.anchorOffset;
			var anchorNode = selected.anchorNode;
			if (extentOffset - anchorOffset > 0) {
				var colorText = anchorNode.textContent.substr(anchorOffset, (extentOffset - anchorOffset));
				var parent = anchorNode.parentElement;
				var elemIndex = 0;
				for (var i=0; i< parent.childNodes.length; i++){
					if(parent.childNodes[i] == anchorNode){
						elemIndex = i;
					}
				}
				colorCommentText(parent, colorText, "", "");
				boxManager.openCommentBox({
					top : e.clientY + window.scrollY,
					left : e.clientX
				}, colorText, function (commentValue) {
					disableComment(parent, colorText, "", "");
					if (commentValue) {
						colorCommentText(parent, colorText, commentValue, "me");
						var uniqueData = {
							url : document.location.href,
							firstId : getFirstElementWithId(parent),
							parentType : parent.nodeName,
							elemIndex: elemIndex,
							text : colorText,
							comment : commentValue
						}
						Background.addComment(uniqueData);
					}
				},"","");
			}
		}
		
	}
	function disableComment(parent, colorText, commentValue, postedBy){
		parent.innerHTML = parent.innerHTML.replace(getColorSapn(colorText, commentValue, postedBy).outerHTML, colorText);
		bindComments(parent);
	}
	
	function colorComments(comments, disable){
		var colorFunc = disable ? disableComment : colorCommentText;
		for (var i = 0; i < comments.length; i++) {
			var comment = comments[i];
			var commentElement = findElement(comment);
			if (commentElement){
				colorFunc(commentElement,
					comment.text,
					comment.comment,
					comment.userName,
					comment.commentId);
			}
		}
	}
	
	
	return {
		findElement: findElement,
		handleSelection: handleSelection,
		colorComments: colorComments
	}
})();

Background = (function (){

	function handleComments(comments){
		if (comments){
			color = comments.color || color;
			if (!comments.disabled) {
				comments = comments.list;
				Comments.showComments(comments)
			} else if(comments){
				enabled = false;
			}
		}
	}
	
	function addComment(uniqueData) {
		var message = {
			type : "addComment",
			data : uniqueData
		};
		chrome.extension.sendMessage(message);
	}
	function getComments() {
		var message = {
			type : "getComments",
			data : document.location.href
		};
		chrome.extension.sendMessage(message, handleComments);
	}
	
	function updateComment(updateData){
		var message = {
			type : "updateComment",
			data : updateData
		};
		chrome.extension.sendMessage(message);
	}
	
	return {
		getComments: getComments,
		addComment: addComment,
		updateComment: updateComment
	}
})();

function init(){
	enabled = true;
	color = "yellow";
	document.onmouseup = DOM.handleSelection;
	Background.getComments();
}

init();


